/************************************************************************
                ConversionRoute.h - Copyright Claudio Botta

This library is free software; you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or 
(at your option) any later version.
This library is distributed in the hope that it will be useful, but 
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public License 
along with this library; if not, write to the 
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
Boston, MA 02110, USA

This file was generated on Sat Mar 15 2008 at 10:58:11
The original location of this file is /home/bottac/geomagick/ConversionRouting.h
**************************************************************************/


#ifndef CONVERSIONROUTE_H
#define CONVERSIONROUTE_H

#include <string>
#include <vector>
#include <deque>
#include <boost/foreach.hpp>
#include "Conversion.h"

#include "BaseTypes/BaseType.h"


#include "geomagickGlobal.h"

using namespace std;


namespace geomagick{

class ConversionRoute;
class ConversionPath 
{

	friend class ConversionRoute;
	public:
	//ConversionPath();
	
	void addConversion(ConversionId* Conversion){
		ConversionChain.push_front(Conversion);
	}
	BaseType* process(BaseType* inBaseType)
	{
		
		foreach(ConversionId* currentConversionId, ConversionChain)
		{
			#if DEBUG
			cout << "Name: "  << (*currentConversionId).getConversionName()  << endl;
			#endif
			inBaseType = (currentConversionId->init())->process(inBaseType);
			
		}
		
		return inBaseType;
	}
	BaseTypeId* from(){return BaseTypeFrom;}
	BaseTypeId* to(){return BaseTypeTo;}	
	void setBaseTypeFrom(BaseTypeId* Id){BaseTypeFrom = Id;}
	void setBaseTypeTo(BaseTypeId* Id){BaseTypeTo = Id;}
	private:
	BaseTypeId* BaseTypeFrom;
	BaseTypeId* BaseTypeTo;
	deque<ConversionId*> ConversionChain;
};


/**
  * class ConversionRouting
  */

class ConversionRoute
{
public:

  // Constructors/Destructors
  //  

  vector<ConversionPath*> ConversionPaths; // !TODO MAKE ME PRIVATE


  // Private attribute accessor methods
  //  

private:

public:


  // Private attribute accessor methods
  //  

  void addConversionPath( ConversionPath* newPath);
  void print()
	{
		int i = 0;
	foreach(ConversionPath* Path, this->ConversionPaths)
		{
		cout << "Path " << i << " from: "<< Path->from()->getTypeName() << " to: " << Path->to()->getTypeName()  << endl; 
		cout << "{" << endl; 
			
			foreach(ConversionId* Conversion, Path->ConversionChain)
			{
				
				
				cout << (*Conversion).getConversionName()  << endl;
				
			}
		cout << "}" << endl;
		}
	}

  BaseType* process(BaseType* BaseTypeIn)
	{
		foreach(ConversionPath* Path, this->ConversionPaths)
		{
			#if DEBUG
			cout << "Comparing "  << (Path->from()->getTypeName())  << " against " 
			<< BaseTypeIn->vgetTypeName() << endl;
			#endif
			if( (Path->from()->getTypeName()).compare(BaseTypeIn->vgetTypeName()) == 0 )
			{
				#if DEBUG
				cout << "Converting :" << Path->from()->getTypeName() << endl;
				#endif 
				
				BaseType* out = Path->process(BaseTypeIn);

				// We're comparing pointers here! Should be OK tough.
				if(Path != (this->ConversionPaths.at(0)) ) delete BaseTypeIn;
				return out;
			}
			
		}
		return NULL;
	}

private:



};
}
#endif // CONVERSIONROUTING_H
